package com.wmapp.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.dom.DOMElement;
import org.springframework.util.StringUtils;

import com.wmapp.DomainConvertException;
import com.wmapp.connect.Request;
import com.wmapp.connect.SocketSupport;
import com.wmapp.domain.MCUConfig;
import com.wmapp.domain.NetworkAddress;
import com.wmapp.domain.RouteItem;
import com.wmapp.domain.SMTP;
import com.wmapp.service.SetupService;
import com.wmapp.utils.DomainUtils;
/**
 * This service is session scope.
 * @author dengl
 *
 */
public class SetupServiceImpl extends SocketSupport implements SetupService{
	private static Log log=LogFactory.getLog(SetupServiceImpl.class);
	
	@Override
	public NetworkAddress getNetworkAddress() {
		NetworkAddress ret=new NetworkAddress();
		String receiveXML=execute(Request.GET_IPADDRESS_REQ);
		
		try {
			if(StringUtils.hasText(receiveXML)){
				Document doc=DocumentHelper.parseText(receiveXML);
				Node nameserver1=doc.selectSingleNode("/interfaces/nameserver1");
				Node nameserver2=doc.selectSingleNode("/interfaces/nameserver2");
				ret.setNameserver1(nameserver1==null?"":nameserver1.getText());
				ret.setNameserver2(nameserver2==null?"":nameserver2.getText());
				List nodes=doc.selectNodes("/interfaces/interface");
				int size=nodes.size();
				if(size>0){
					Element et0=(Element)nodes.get(0);
					ret.setIf0ip(et0.elementText("ip"));
					ret.setIf0mac(et0.elementText("mac"));
					ret.setIf0mask(et0.elementText("mask"));
					ret.setIf0gw(et0.elementText("gateway"));
					
					if(size>1){
						ret.setHasif1(true);
						Element et1=(Element)nodes.get(1);
						ret.setIf1ip(et1.elementText("ip"));
						ret.setIf1mac(et1.elementText("mac"));
						ret.setIf1mask(et1.elementText("mask"));
						ret.setIf1gw(et1.elementText("gateway"));
					}
				}
			}
		} catch (DocumentException e) {
			log.error(e.getMessage(), e);
			throw new DomainConvertException(e.getMessage());
		}
		
		return ret;
	}
	
	@Override
	public void saveNetworkAddress(NetworkAddress networkAddress) {
		Map params=DomainUtils.domain2Map(networkAddress, NetworkAddress.SAVE_FIELDS);
		
		execute(Request.PUT_IPADDRESS_REQ, params,Request.PUT_IPADDRESS_REQ);
	}
	
	@Override
	public void rebootMCU() {
		execute(Request.REBOOT_REQ);
	}
	
	@Override
	public List<RouteItem> queryRoutes() {
		List<RouteItem> ret=null;
		String receiveXML=execute(Request.GET_ROUTETABLE_REQ);
		
		ret = DomainUtils.xml2List(receiveXML, "/routeTable/routeItem", RouteItem.class);
		
		return ret;
	}
	
	@Override
	public MCUConfig getMCUConfig() {
		MCUConfig ret=null;
		
		String receiveXML=execute(Request.GET_CONFIG_REQ);
		
		try {
			if(StringUtils.hasText(receiveXML)){
				Document doc=DocumentHelper.parseText(receiveXML);
				ret=(MCUConfig)DomainUtils.element2Domain(doc.getRootElement(), MCUConfig.class);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new DomainConvertException(e.getMessage());
		}
		
		return ret;
	}
	
	@Override
	public void saveMCUConfig(MCUConfig mcuConfig) {
		Map params=DomainUtils.domain2Map(mcuConfig,MCUConfig.SAVE_FIELDS);
		execute(Request.PUT_CONFIG_REQ, params,Request.PUT_CONFIG_REQ);
	}
	
	@Override
	public void addRoute(RouteItem routeItem) {
		Map params=new HashMap<String, String>();
		
		params.put("net", routeItem.getNet());
		params.put("netmask", routeItem.getNetmask());
		params.put("interface", routeItem.getIface());
		
		execute(Request.ADD_ROUTETABLE_REQ, params, "routeItem");
	}
	
	@Override
	public void removeRoutes(List<RouteItem> items) {
		Document doc=DocumentHelper.createDocument();
		Element root=doc.addElement("routeTable");
		
		for (Iterator iterator = items.iterator(); iterator.hasNext();) {
			RouteItem routeItem = (RouteItem) iterator.next();
			Element et = new DOMElement("routeItem");
			
			et.addElement("net").setText(routeItem.getNet());
			et.addElement("netmask").setText(routeItem.getNetmask());
			et.addElement("interface").setText(routeItem.getIface());
			
			root.add(et);
		}
		
		execute(Request.DEL_ROUTETABLE_REQ, doc.asXML());
	}
	
	@Override
	public void modifyTime(Date date) {
		if(date!=null){
			Map params=new HashMap<String,String>();
			SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String d=format.format(date);
			
			String[] dd=d.split(" ");
			
			if(dd.length>0){
				params.put("date", dd[0]);
				if(dd.length>1){
					params.put("time", dd[1]);
				}
			}
			
			if(!params.isEmpty()){
				execute(Request.PUT_TIME_REQ,params,"dateAndTime");
			}
		}
	}
	
	@Override
	public SMTP getSMTP() {
		SMTP ret=null;
		
		try {
			Document doc=DocumentHelper.parseText(execute(Request.GET_SMTP_REQ));
			ret=(SMTP)DomainUtils.element2Domain(doc.getRootElement(),SMTP.class);
		} catch (DocumentException e) {
			log.error(e.getMessage(), e);
			throw new DomainConvertException(e.getMessage());
		}
		
		return ret;
	}
	
	@Override
	public void saveSMTP(SMTP smtp) {
		Map params=DomainUtils.domain2Map(smtp,SMTP.SAVE_FIELDS);
		
		execute(Request.PUT_SMTP_REQ, params,"smtp");
	}
}
